package cn.tedu.csmall.stock.webapi.controller;

import cn.tedu.csmall.commons.exception.CoolSharkServiceException;
import cn.tedu.csmall.commons.pojo.stock.dto.StockReduceCountDTO;
import cn.tedu.csmall.commons.restful.JsonResult;
import cn.tedu.csmall.commons.restful.ResponseCode;
import cn.tedu.csmall.stock.service.IStockService;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/base/stock")
@Api(tags = "库存管理")
public class StockController {

    @Autowired
    private IStockService stockService;

    @GetMapping("/reduce/count")
    @ApiOperation("减少商品库存数")
    // SentinelResource注解标记的控制器方法,会被Sentinel管理
    // 在这个方法第一次运行后,可以在sentinel仪表台界面中设置限流规则
    // "减少库存的方法"设置当前方法在仪表台中显示的名称
    // blockHandler 指定请求被限流时运行的方法名称
    // fallback 指定控制器方法发生异常时,要执行的降级方法名称
    @SentinelResource(value = "减少库存的方法",blockHandler = "blockError",
                        fallback = "fallbackError")
    public JsonResult reduceCommodityCount(StockReduceCountDTO stockReduceCountDTO) {
//        if(Math.random()<0.5){
//            throw new CoolSharkServiceException(ResponseCode.INTERNAL_SERVER_ERROR,
//                                                    "抛出随机异常!");
//        }
        // 调用业务逻辑层
        stockService.reduceCommodityCount(stockReduceCountDTO);
        return JsonResult.ok("商品库存减少完成!");
    }

    // Sentinel 自定义限流方法的定义
    // 1.访问修饰符必须是public
    // 2.返回值类型必须和限流的控制器方法一致
    // 3.方法名称必须是限流注解中定义的blockHandler指定的方法名称
    // 4.方法参数列表必须和限流的控制器方法一致,而且还要添加一个BlockException类型的参数
    public JsonResult blockError(StockReduceCountDTO stockReduceCountDTO, BlockException e){
        // 限流方法一般直接返回限流信息即可
        return JsonResult.failed(ResponseCode.BAD_REQUEST,"服务器忙,请稍后再试");
    }

    // 这个方法是Sentinel注解中fallback指定的降级方法
    // 当原定运行的控制器方法发送异常时,Sentinel会运行下面的方法
    // 降级方法中,可以编写一些对正常逻辑的补救措施,使用户受到的损失最少
    public JsonResult fallbackError(StockReduceCountDTO stockReduceCountDTO){
        return JsonResult.failed(ResponseCode.BAD_REQUEST,"因为运行时发生异常,服务降级");
    }


}






